home *** CD-ROM | disk | FTP | other *** search
/ Atari Mega Archive 1 / Atari Mega Archive - Volume 1.iso / gnu / gas / gassrc04.zoo / vms-dbg.c < prev    next >
C/C++ Source or Header  |  1991-01-24  |  38KB  |  1,126 lines

  1. #include <stdio.h>
  2. #include "as.h"
  3. #include "struc-symbol.h"
  4. #include "symbols.h"
  5. #include "objrecdef.h"
  6. #include <stab.h>
  7.  
  8. /* This file contains many of the routines needed to output debugging info into
  9.  * the object file that the VMS debugger needs to understand symbols.  These
  10.  * routines are called very late in the assembly process, and thus we can be
  11.  * fairly lax about changing things, since the GSD and the TIR sections have
  12.  * already been output.
  13.  */
  14.  
  15. /* We need this info to cross correlate between the stabs def for a symbol and
  16.  * the actual symbol def.  The actual symbol def contains the psect number and
  17.  * offset, which is needed to declare a variable to the debugger for global
  18.  * and static variables
  19.  */
  20. struct VMS_Symbol {
  21.     struct VMS_Symbol *Next;
  22.     struct symbol *Symbol;
  23.     int Size;
  24.     int Psect_Index;
  25.     int Psect_Offset;
  26.     };
  27. extern struct VMS_Symbol *VMS_Symbols;
  28.  
  29. enum advanced_type {BASIC,POINTER,ARRAY,ENUM,STRUCT,UNION,FUNCTION,VOID,UNKNOWN};
  30.  
  31. /* this structure contains the information from the stabs directives, and the
  32.  * information is filled in by VMS_typedef_parse.  Everything that is needed
  33.  * to generate the debugging record for a given symbol is present here.
  34.  * This could be done more efficiently, using nested struct/unions, but for now
  35.  * I am happy that it works.
  36.  */
  37. struct VMS_DBG_Symbol{
  38.     struct VMS_DBG_Symbol * next;
  39.     enum advanced_type advanced;    /* description of what this is */
  40.     int dbx_type;    /* this record is for this type */
  41.     int type2;    /* For advanced types this is the type referred to.
  42.                 i.e. the type a pointer points to, or the type
  43.                 of object that makes up an array */
  44.     int VMS_type;    /* Use this type when generating a variable def */
  45.     int index_min;    /* used for arrays - this will be present for all */
  46.     int index_max;    /* entries, but will be meaningless for non-arrays */
  47.     int data_size;    /* size in bytes of the data type.  For an array, this
  48.                is the size of one element in the array */
  49.     int struc_numb; /* Number of the structure/union/enum - used for ref */
  50. };
  51.  
  52. struct VMS_DBG_Symbol *VMS_Symbol_type_list={(struct VMS_DBG_Symbol*) NULL};
  53.  
  54. /* we need this structure to keep track of forward references to
  55.  * struct/union/enum that have not been defined yet.  When they are ultimately
  56.  * defined, then we can go back and generate the TIR commands to make a back
  57.  * reference.
  58.  */
  59.  
  60. struct forward_ref{
  61.     struct forward_ref * next;
  62.     int dbx_type;
  63.     int struc_numb;
  64.     char resolved;
  65.     };
  66.  
  67. struct forward_ref * f_ref_root={(struct forward_ref*) NULL};
  68.  
  69. static char * symbol_name;
  70. static structure_count=0;
  71.  
  72. /* this routine converts a number string into an integer, and stops when it
  73.  * sees an invalid character the return value is the address of the character 
  74.  * just past the last character read.  No error is generated.
  75.  */
  76. static char * cvt_integer(char* str,int * rtn){
  77.     int ival, neg;
  78.         neg = *str == '-' ? ++str, -1 : 1;
  79.         ival=0;    /* first get the number of the type for dbx */
  80.         while((*str <= '9') && (*str >= '0'))
  81.             ival = 10*ival + *str++ -'0';
  82.     *rtn = neg*ival;
  83.     return str;
  84. }
  85.  
  86. /* this routine fixes the names that are generated by C++, ".this" is a good
  87.  * example.  The period does not work for the debugger, since it looks like
  88.  * the syntax for a structure element, and thus it gets mightily confused
  89.  */
  90. static fix_name(char* pnt){
  91.     for( ;*pnt != 0; pnt++){
  92.     if(*pnt == '.') *pnt = '$';
  93.     };
  94. }
  95.  
  96. /* this routine is used to compare the names of certain types to various
  97.  * fixed types that are known by the debugger.
  98.  */
  99. #define type_check(x)  !strcmp( symbol_name , x )
  100.  
  101. /* When defining a structure, this routine is called to find the name of
  102.  * the actual structure.  It is assumed that str points to the equal sign
  103.  * in the definition, and it moves backward until it finds the start of the
  104.  * name.  If it finds a 0, then it knows that this structure def is in the
  105.  * outermost level, and thus symbol_name points to the symbol name.
  106.  */
  107. static char* get_struct_name(char* str){
  108.     char* pnt;
  109.     pnt=str;
  110.     while((*pnt != ':') && (*pnt != '\0')) pnt--;
  111.     if(*pnt == '\0') return symbol_name;
  112.     *pnt-- = '\0';
  113.     while((*pnt != ';') && (*pnt != '=')) pnt--;
  114.     if(*pnt == ';') return pnt+1;
  115.     while((*pnt < '0') || (*pnt > '9')) pnt++;
  116.     while((*pnt >= '0') && (*pnt <= '9')) pnt++;
  117.     return pnt;
  118. }    
  119. /* search symbol list for type number dbx_type.  Return a pointer to struct */
  120. static struct VMS_DBG_Symbol* find_symbol(int dbx_type){
  121.     struct VMS_DBG_Symbol* spnt;
  122.     spnt=VMS_Symbol_type_list;
  123.     while (spnt!=(struct VMS_DBG_Symbol*) NULL){
  124.         if(spnt->dbx_type==dbx_type) break;
  125.         spnt=spnt->next;};
  126.     if(spnt==(struct VMS_DBG_Symbol*) NULL) return 0;/*Dunno what this is*/
  127.     return spnt;
  128. }
  129.  
  130.  
  131. /* Many good programmers cringe when they see a fixed size array - since I am
  132.  * using this to generate the various descriptors for the data types present,
  133.  * you might argue that the descriptor could overflow the array for a
  134.  * complicated variable, and then I am in deep doo-doo.  My answer to this is
  135.  * that the debugger records that we write have all sorts of length bytes
  136.  * stored in them all over the place, and if we exceed 127 bytes (since the top
  137.  * bit indicates data, rather than a command), we are dead anyhow.  So I figure
  138.  * why not do this the easy way.  Besides, to get 128 bytes, you need something
  139.  * like an array with 10 indicies, or something like
  140.  *       char **************************************** var; 
  141.  * Lets get real.  If some idiot writes programs like that he/she gets what
  142.  * they deserve.  (It is possible to overflow the record with a somewhat
  143.  * simpler example, like: int (*(*(*(*(*(* sarr6)[1])[1])[2])[3])[4])[5];
  144.  * but still...).  And if someone in the peanut gallery wants to know "What
  145.  * does VAX-C do with something like this?", I will tell you.  It crashes.
  146.  * At least this code has the good sense to convert it to *void.
  147.  * In practice, I do not think that this presents too much of a problem, since
  148.  * struct/union/enum all use defined types, which sort of terminate the
  149.  * definition.  It occurs to me that we could possibly do the same thing with
  150.  * arrays and pointers, but I don't know quite how it would be coded.
  151.  *
  152.  * And now back to the regularly scheduled program...
  153.  */
  154. #define MAX_DEBUG_RECORD 128
  155. static char Local[MAX_DEBUG_RECORD]; /* buffer for variable descriptor */
  156. static int Lpnt;        /* index into Local */
  157. static char Asuffix[MAX_DEBUG_RECORD]; /* buffer for array descriptor */
  158. static int Apoint;    /* index into Asuffix */
  159. static char overflow;    /* flag to indicate we have written too much*/
  160. static int total_len;    /* used to calculate the total length of variable
  161.             descriptor plus array descriptor - used for len byte*/
  162. static int struct_number;    /* counter used to assign indexes to struct
  163.                     unions and enums */
  164.  
  165. /* this routine puts info into either Local or Asuffix, depending on the sign
  166.  * of size.  The reason is that it is easier to build the variable descriptor
  167.  * backwards, while the array descriptor is best built forwards.  In the end
  168.  * they get put together, if there is not a struct/union/enum along the way
  169.  */
  170. push(int value, int size){
  171.     char * pnt;
  172.     int i;
  173.     int size1;
  174.     long int val;
  175.     val=value;
  176.     pnt=(char*) &val;
  177.     size1 = size;
  178.     if (size < 0) {size1 = -size; pnt += size1-1;};
  179.     if(size < 0)
  180.     for(i=0;i<size1;i++) {
  181.         Local[Lpnt--] = *pnt--;
  182.         if(Lpnt < 0) {overflow = 1; Lpnt = 1;};}
  183.     else for(i=0;i<size1;i++){
  184.          Asuffix[Apoint++] = *pnt++;
  185.          if(Apoint >= MAX_DEBUG_RECORD) 
  186.             {overflow = 1; Apoint =MAX_DEBUG_RECORD-1;};}
  187. }
  188.  
  189. /* this routine generates the array descriptor for a given array */
  190. static array_suffix(struct VMS_DBG_Symbol* spnt2){
  191.     struct VMS_DBG_Symbol * spnt;
  192.     struct VMS_DBG_Symbol * spnt1;
  193.     int rank;
  194.     int total_size;
  195.     int i;
  196.     rank=0;
  197.     spnt=spnt2;
  198.     while(spnt->advanced != ARRAY) {
  199.         spnt=find_symbol(spnt->type2);
  200.         if(spnt == (struct VMS_DBG_Symbol *) NULL) return;};
  201.     spnt1=spnt;
  202.     spnt1=spnt;
  203.     total_size= 1;
  204.     while(spnt1->advanced == ARRAY) {rank++;
  205.         total_size *= (spnt1->index_max - spnt1->index_min +1);
  206.         spnt1=find_symbol(spnt1->type2);};
  207.     total_size = total_size * spnt1->data_size;
  208.     push(spnt1->data_size,2);
  209.     if(spnt1->VMS_type == 0xa3) push(0,1);
  210.             else push(spnt1->VMS_type,1);
  211.     push(4,1);
  212.     for(i=0;i